﻿using System;

namespace Cpu6502.Opcodes
{
    public class Opcode
    {        
        public CPU.AddressType AddressType;

        /// <summary>
        /// Number of CPU Cycles used by the OpCode
        /// </summary>
        public int CpuCycles = 0;

        /// <summary>
        /// Returns the argument for this Opcode.
        /// </summary>
        public Int16 Argument
        {
            get
            {
                if (this.ArgumentLength == 2)
                {
                    return (Int16)(CPU.Memory[CPU.PC + 1] | (CPU.Memory[CPU.PC + 2] << 8));
                }
                else if (this.ArgumentLength == 1)
                {
                    return (CPU.Memory[CPU.PC + 1]);
                }

                return 0;
            }
        }

        /// <summary>
        /// Returns the length (in Bytes) of the argument
        /// </summary>
        public int ArgumentLength
        {
            get
            {
                if (this.AddressType == CPU.AddressType.Absolute ||
                    this.AddressType == CPU.AddressType.AbsoluteIndexedX ||
                    this.AddressType == CPU.AddressType.AbsoluteIndexedY || 
                    this.AddressType == CPU.AddressType.Relative ||
                    this.AddressType == CPU.AddressType.IndirectAbsolute)                    
                {
                    return 2;
                }
                else if (this.AddressType == CPU.AddressType.Immediate ||
                    this.AddressType == CPU.AddressType.ZeroPage ||
                    this.AddressType == CPU.AddressType.ZeroPageIndexedX ||
                    this.AddressType == CPU.AddressType.ZeroPageIndexedY ||
                    this.AddressType == CPU.AddressType.IndexedIndirect ||
                    this.AddressType == CPU.AddressType.IndirectIndexed ||
                    this.AddressType == CPU.AddressType.Accumulator)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }
            }
        }

        /// <summary>
        /// Executes the Opcode
        /// </summary>
        public virtual void Execute()
        {
        }
    }
}
